package warthog.parsegen;

import java.util.ArrayList;
import java.util.List;

import warthog.cradle.JavaClass;

public class Sym implements Comparable<Sym> {
	final String name;
	int id; // It's convenient in the output phase for each symbol to know its own ID.
	public String toString() { return name; }
	private List<Rule> alternatives = new ArrayList<Rule>();
	boolean term = true;
	boolean lambda = false;
	int precedence = 0;
	
	SemanticClass semanticClass = SemanticClass.VOID.theVOID;
	
	Sym(String name) {this.name = name;}	// Promise to keep them unique!
	void produce(Rule r) {
		if (precedence>0) throw new RuntimeException("nonterminal "+name+" can't have precedence.");
		term = false;
		alternatives.add(r);
		if (r.isEpsilon()) lambda = true;
	}
	/**
	 * @return true if the lambda state changed.
	 */
	public boolean check_lambda() {
		if (this.lambda) return false;
		for (Rule r:alternatives) if (r.is_lambda()) {
			this.lambda = true;
			return true;
		}
		return false;
	}
	public List<Dot> front() {
		List<Dot> out = new ArrayList<Dot>(alternatives.size());
		for (Rule r:alternatives) out.add(r.front());
		return out;
	}
	public void setPrecedence(int pLevel) {
		precedence = pLevel;
		if (!term) throw new RuntimeException("nonterminal "+name+" can't have precedence.");
	}
	void writePop(JavaClass cw, int posn) { semanticClass.writePop(cw, posn); }
	void writeDeclareHead(JavaClass cw) { semanticClass.writeDeclareHead(cw); }
	void writePush(JavaClass cw) { semanticClass.writePush(cw); }
	public String javaType() { return semanticClass.javaType(); }
	@Override
	public int compareTo(Sym o) {
		if (null == name) return -1;
		if (null == o.name) return 1;
		return name.compareTo(o.name);
	}
	boolean isVoid() {
		return semanticClass==SemanticClass.VOID.theVOID;
	}
}